---
title: "Module 11: Writing Pythonic Code"
description: "Learn how to write idiomatic, elegant, and efficient Python code, and truly think like a Python developer."
---

## 1. Introduction

Every programming language has its own unique style and philosophy. The word "Pythonic" is used to describe a style of code that follows the best practices recognized by the Python community, makes full use of the language's features, and is concise, readable, and efficient.

For developers coming from JavaScript, just mastering the syntax is not enough. Learning to write Pythonic code means starting to think about and solve problems in "the Python way."

> 💡 **Learning Strategy**: Think of writing Pythonic code as learning the "idioms" and "slang" of a language. It will make your code more welcome in the community and easier for others to understand and maintain.

## 2. List Comprehensions

List comprehensions are one of the most iconic features of Python. They provide a concise and elegant way to create new lists based on existing ones, and are often more readable than using `map()` and `filter()`.

<PythonEditor title="List Comprehensions vs. map/filter" compare={true}>
```javascript !! js
// JavaScript (map and filter)
const numbers = [1, 2, 3, 4, 5];

// Get the squares of all numbers
const squares = numbers.map(n => n * n);

// Get the squares of all even numbers
const evenSquares = numbers
  .filter(n => n % 2 === 0)
  .map(n => n * n);
```

```python !! py
# Python (List Comprehensions)
numbers = [1, 2, 3, 4, 5]

# Get the squares of all numbers (Pythonic)
squares = [n * n for n in numbers]

# Get the squares of all even numbers (Pythonic)
even_squares = [n * n for n in numbers if n % 2 == 0]

# Non-Pythonic way
even_squares_long = list(map(lambda n: n * n, filter(lambda n: n % 2 == 0, numbers)))
```
</PythonEditor>

## 3. EAFP vs LBYL

These are two different programming styles, and the Python community generally prefers EAFP.

*   **LBYL (Look Before You Leap)**: Perform various checks before performing an operation. This is common in JavaScript.
*   **EAFP (Easier to Ask for Forgiveness than Permission)**: Try to perform the operation directly, and if a problem (exception) occurs, then handle it.

<PythonEditor title="EAFP vs. LBYL Comparison" compare={true}>
```javascript !! js
// JavaScript (LBYL style)
const user = { profile: { name: 'Alice' } };

if (user && user.profile && user.profile.name) {
  console.log(user.profile.name);
} else {
  console.log('Name not found');
}

// More concise with optional chaining operator ?.
console.log(user?.profile?.name || 'Name not found');
```

```python !! py
# Python (EAFP style - Pythonic)
user = {"profile": {"name": "Alice"}}

try:
    print(user["profile"]["name"])
except (KeyError, TypeError):
    print("Name not found")

# Python (LBYL style - less Pythonic)
if "profile" in user and isinstance(user["profile"], dict) and "name" in user["profile"]:
    print(user["profile"]["name"])
else:
    print("Name not found")
```
</PythonEditor>

## 4. Using `enumerate` for Iteration

When you need both the index and the value in a loop, don't use `range(len(my_list))`. The Pythonic way is to use the built-in function `enumerate`.

<PythonEditor title="enumerate vs. range(len(...))" compare={true}>
```javascript !! js
// JavaScript
const items = ['a', 'b', 'c'];

items.forEach((item, index) => {
  console.log(`Index: ${index}, Item: ${item}`);
});
```

```python !! py
# Python (Pythonic)
items = ['a', 'b', 'c']

for index, item in enumerate(items):
    print(f"Index: {index}, Item: {item}")

# Python (less Pythonic)
for i in range(len(items)):
    print(f"Index: {i}, Item: {items[i]}")
```
</PythonEditor>

## 5. Unpacking

Python allows you to "unpack" the elements of an iterable (like a list or tuple) into multiple variables. This makes the code more concise.

<PythonEditor title="Unpacking vs. Manual Assignment" compare={true}>
```javascript !! js
// JavaScript (Destructuring assignment)
const point = [10, 20, 30];
const [x, y, z] = point;

const [first, ...rest] = [1, 2, 3, 4];
// first = 1, rest = [2, 3, 4]
```

```python !! py
# Python (Unpacking)
point = (10, 20, 30)
x, y, z = point

# Starred expression (similar to JS rest)
first, *rest, last = [1, 2, 3, 4, 5]
# first = 1, rest = [2, 3, 4], last = 5
```
</PythonEditor>

## 6. Using the `with` Statement to Manage Resources

As mentioned in the "Common Pitfalls" module, using the `with` statement (context manager) is the most Pythonic way to handle resources that need to be explicitly closed (like files, database connections). It ensures that the resource is properly released even if an error occurs.

<PythonEditor title="with statement vs. try...finally" compare={true}>
```javascript !! js
// JavaScript (No direct equivalent, usually use try...finally)
let resource;
try {
  resource = acquireResource();
  // use resource
} finally {
  if (resource) {
    releaseResource(resource);
  }
}
```

```python !! py
# Python (Pythonic)
with open("my_file.txt", "r") as f:
    content = f.read()
    # The file is automatically closed, even if an error occurs during reading

# Python (less Pythonic)
f = open("my_file.txt", "r")
try:
    content = f.read()
finally:
    f.close()
```
</PythonEditor>

## 7. Summary

Writing Pythonic code is an ongoing process that is about code readability, conciseness, and efficiency. When you start to naturally use list comprehensions, `enumerate`, and the `with` statement, you are truly on your way to becoming an idiomatic Python developer.

**Core Principle**: Code is written for people to read first, and for machines to execute second. Pythonic code is the best embodiment of this principle.